package com.nulldev.util.other;

import java.text.DecimalFormat;
import java.util.concurrent.ExecutorService;

import com.nulldev.util.logging.Logger;
import com.nulldev.util.logging.LoggerFactory;
import com.nulldev.util.math.lNumber;
import com.nulldev.util.threading.legacy.ThreadExecutor;

public class lTimer implements Runnable {

	protected long UPDATE_RATE = 5L;
	private lNumber TICK = lNumber.fromLong(0L);
	private boolean paused;
	private boolean stop;
	
	private final static Logger log = LoggerFactory.getLogger(true, true);

	public lTimer() {
	}

	public void start() {
		ThreadExecutor.execute(this);
	}

	public void start(final ExecutorService serv) {
		serv.execute(this);
	}

	@Override
	public void run() {
		while (true) {
			if (this.stop) {
				break;
			}
			if (!this.paused) {
//				if (this.TICK + 1 > Long.MAX_VALUE) {
//					this.TICK = Long.MIN_VALUE;
//					log.
//					error("Timer on thread '" + "nullUtil: Timer" + "' has reached max value. It has been set to the minimal value to prevent overflow.");
//				}
				this.TICK.addSelf(this.UPDATE_RATE);
				updateF();
				try {
					Thread.sleep(this.UPDATE_RATE);
				} catch (InterruptedException e) {
				}
			}else {
				try {
					Thread.sleep(this.UPDATE_RATE);
				} catch (InterruptedException e) {
				}
			}
		}
	}
	
	void updateF() {
	}

	public lNumber ticks() {
		return this.TICK;
	}

	public String ticks2s() {
		final DecimalFormat frm = new DecimalFormat("#.#");
		return frm.format(this.TICK.divide(1000L).longValue()) + "s";
	}

	public void reset() {
		this.TICK.setSelf(0L);
	}

	public void update(final long newValue) {
		this.TICK.setSelf(newValue);
	}

	public void pause() {
		this.paused = true;
	}

	public void unpause() {
		this.paused = false;
	}

	public void add(final long val) {
		this.TICK.addSelf(val);
	}

	public void setDelay(final long RATE) {
		this.UPDATE_RATE = RATE;
	}

	public boolean isTicks(final long ticks) {
		final boolean out = (this.TICK.longValue() % ticks != 0);
		return out;
	}
	
	public boolean hasReached(final long ticks) {
		return this.TICK.moreThan(ticks);
	}

	public void stop() {
		this.stop = true;
	}
}
